#ifndef __DRIVER_H__
#define __DRIVER_H__

#include <pspkernel.h>
#include <pspdebug.h>
#include <pspkdebug.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pspusb.h>
#include <pspusbbus.h>
#include "../states.h"

#define DRIVER_NAME "HUBDRV"

#include "defines.h"

struct usb_hub_header_descriptor {
	unsigned char  bLength;				/* 8+n */
	unsigned char  bDescriptorType;		/* USB_DT_CS_HUB */
	unsigned char  bNbrPorts;			/* n */
	unsigned short wHubCharacteristics;	/* hub characteristics */
	unsigned char  bPwrOn2PwrGood;		/* Port settling time, in 2ms */
	unsigned char  bHubContrCurrent;	/* ? */
	unsigned char  DeviceRemovable;		/* [n/8] */
	unsigned char  PortPwrCtrlMask;		/* [n/8] */
} __attribute__ ((packed));


struct UsbbdDeviceRequest {
	struct UsbEndpoint *endpoint;
	void *data;
	int  size;
	int  isControlRequest;
	void (*onComplete) (struct UsbbdDeviceRequest *req);
	int  transmitted;
	int  returnCode;
	struct UsbbdDeviceRequest *next;
	void *unused;
	void *physicalAddress;
};

struct InterfaceSettings {
	struct InterfaceDescriptor *descriptors;
	unsigned int alternateSetting;
	unsigned int numDescriptors;
};

extern struct UsbDriver PS3HubDriver;
extern int switch_to_port_delayed;
extern int current_port;
extern struct UsbData usbdata[2];
extern u8 portaddress[8];
extern struct UsbbdDeviceRequest request;
extern struct UsbbdDeviceRequest hub_request;
extern int comstatus;
extern int driver_connected;

/* Functions */
extern int usb_request(int arg1, int arg2, struct DeviceRequest *req);
extern int usb_func28(int arg1, int arg2, int arg3);
extern int usb_attach(int speed, void *arg2, void *arg3);
extern int usb_detach(int arg1, int arg2, int arg3);
extern int start_func(int size, void *p);
extern int stop_func(int size, void *p);
extern void usb_configure (int usb_version, int desc_count, struct InterfaceSettings *settings);
extern int usb_interrupt_handler (void);

/* Hub ones */
extern void hub_complete_request (struct UsbbdDeviceRequest *req);
extern void dev_complete_request (struct UsbbdDeviceRequest *req);
extern void complete_request (struct UsbbdDeviceRequest *req);

extern void hub_interrupt_transmit();
extern void hub_port_changed();
extern void hub_connect_port (unsigned int port);
/* Communication */
#define DEBUG(...) { char mitext[500]; sprintf(mitext,__VA_ARGS__); strcat(pdata->text,mitext); }

#endif